package com.jwsoft.manager.core.dao.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bifang.engine.assistant.core.enums.AuthStatusEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.module.base.core.helper.DictHelper;
import com.jwsoft.manager.common.enums.MatchingStatusEnum;
import com.jwsoft.manager.common.enums.SchoolCategoryEnum;
import com.jwsoft.manager.common.vo.eduAddress.EduAddressQueryVO;
import com.jwsoft.manager.common.vo.eduAddress.EduAddressStatisticsVO;
import com.jwsoft.manager.core.dao.mapper.EduAddressMapper;
import com.jwsoft.manager.core.dao.mapper.EduAddressSchoolAuditMapper;
import com.jwsoft.manager.core.dao.mapper.EduAddressSchoolMapper;
import com.jwsoft.manager.core.dao.model.EduAddress;
import com.jwsoft.manager.core.dao.model.EduAddressSchool;
import com.jwsoft.manager.core.dao.model.EduAddressSchoolAudit;
import com.jwsoft.manager.core.dao.service.EduAddressService;
import com.jwsoft.manager.core.util.EduHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * 地址表服务实现类
 *
 * @author wangtao
 * @since 2022-11-24
 */
@Service
public class EduAddressServiceImpl extends ServiceImpl<EduAddressMapper, EduAddress> implements EduAddressService {

    @Autowired
    DictHelper dictHelper;

    @Autowired
    private EduAddressSchoolAuditMapper addressSchoolAuditMapper;

    @Autowired
    private EduAddressSchoolMapper addressSchoolMapper;

    @Autowired
    private EduHelper eduHelper;
    @Override
    public String saveByAddress(String address,Integer year,String bnxxFlag,String bnczFlag) {
        if(StringUtils.isBlank(bnczFlag)){
            bnczFlag=BoolEnum.TRUE.getType();
        }
        if(StringUtils.isBlank(bnxxFlag)){
            bnxxFlag=BoolEnum.TRUE.getType();
        }
        String dbcAddress = Convert.toDBC(address);
        QueryWrapper<EduAddress> addressQueryWrapper = new QueryWrapper<>();
        addressQueryWrapper.lambda().eq(EduAddress::getAddressName, dbcAddress);
        List<EduAddress> addressList = this.list(addressQueryWrapper);
        if (!ObjectUtils.isEmpty(addressList) && addressList.size() >= 1) {
            String addressId=addressList.get(0).getAddressId();
            UpdateWrapper<EduAddress> updateWrapper=new UpdateWrapper<>();
            updateWrapper.lambda().eq(EduAddress::getAddressId,addressId)
                    .set(EduAddress::getBnxxFlag,bnxxFlag)
                    .set(EduAddress::getBnczFlag,bnczFlag)
                    .set(EduAddress::getMatchingStatus,BoolEnum.FALSE.getType())
                    .set(EduAddress::getYear,year);
            this.update(updateWrapper);
            return addressId;
        } else {
            EduAddress eduAddress = new EduAddress();
            eduAddress.setAddressId(IdUtil.simpleUUID());
            eduAddress.setAddressCode(eduAddress.getAddressId());
            eduAddress.setFiexed(BoolEnum.TRUE.getType());
            eduAddress.setAddressName(dbcAddress);
            eduAddress.setFictitious(BoolEnum.FALSE.getType());
            eduAddress.setStatus(BoolEnum.TRUE.getType());
            eduAddress.setLocationStatus(BoolEnum.FALSE.getType());
            eduAddress.setHandleStatus(BoolEnum.FALSE.getType());
            eduAddress.setMatchingStatus(BoolEnum.FALSE.getType());
            eduAddress.setBnczFlag(bnczFlag);
            eduAddress.setBnxxFlag(bnxxFlag);
            eduAddress.setYear(year);
            if (StringUtils.isBlank(eduAddress.getAuthStatus())) {
                eduAddress.setAuthStatus(AuthStatusEnum.YES.getType());
            }
            this.save(eduAddress);
            return eduAddress.getAddressId();
        }
    }

    @Override
    public List<EduAddress> getAddressByTreeId(Long treeId) {
        QueryWrapper<EduAddress> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduAddress::getAddressTreeId, treeId);
        return this.list(queryWrapper);
    }

    @Override
    public List<EduAddress> getList(EduAddressQueryVO vo) {
        List<EduAddress> list = new ArrayList<>();
        if (vo.getLimitCount() == 0){
            vo.setLimitCount(1000);
        }
        list = baseMapper.getList(vo);
        return list;
    }

    /**
     * 校验地址学区的匹配状态
     * 校验是有待审核数据，并且学校地址关联表是否有数据
     * @param eduAddress
     */
    @Override
    public void checkAddressMatchingStatus(EduAddress eduAddress) {
        //根据地址id，查询地址学校关联审核表的审核状态
        QueryWrapper<EduAddressSchoolAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduAddressSchoolAudit::getAddressId,eduAddress.getAddressId())
                .eq(EduAddressSchoolAudit::getAuthStatus,AuthStatusEnum.NODO.getType());
        addressSchoolAuditMapper.selectCount(queryWrapper);
        if (addressSchoolAuditMapper.selectCount(queryWrapper) > 0){
           return;
        }
        //如果一条待审核数据都没有 ,判断edu_address_school是否有关联数据
        QueryWrapper<EduAddressSchool> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(EduAddressSchool::getAddressId,eduAddress.getAddressId());
        if (addressSchoolMapper.selectCount(wrapper) > 0){
            eduAddress.setMatchingStatus(MatchingStatusEnum.SUCCESS.getType());
            eduAddress.setMatchingMessage(MatchingStatusEnum.SUCCESS.getName());
            this.updateById(eduAddress);
        }else{
            eduAddress.setMatchingStatus(MatchingStatusEnum.NODO.getType());
            eduAddress.setMatchingMessage(MatchingStatusEnum.NODO.getName());
            this.updateById(eduAddress);
        }
    }

    @Override
    public List<EduAddressStatisticsVO> toBeReviewedAddressStatistics(EduAddressQueryVO vo, String auditBnFlag) {
        List<EduAddressStatisticsVO> eduAddressStatisticsVOS = new ArrayList<>();

        //如果传入本年本学段标志
        if (BoolEnum.TRUE.getType().equals(auditBnFlag)) {
            if (StringUtils.isBlank(vo.getSchoolCategory())) {
                // 如果前端没有传入学段，则小学查询一遍，初中查询一遍，最后组合起来
                EduAddressQueryVO primaryVO = new EduAddressQueryVO();
                BeanUtils.copyProperties(vo, primaryVO);
                primaryVO.setSchoolCategory(SchoolCategoryEnum.PRIMARY.getType());
                List<EduAddressStatisticsVO> primaryList = baseMapper.toBeReviewedAddressStatistics(primaryVO);

                EduAddressQueryVO juniorVO = new EduAddressQueryVO();
                BeanUtils.copyProperties(vo, juniorVO);
                juniorVO.setSchoolCategory(SchoolCategoryEnum.JUNIOR.getType());
                List<EduAddressStatisticsVO> juniorList = baseMapper.toBeReviewedAddressStatistics(juniorVO);

                if (!CollectionUtils.isEmpty(primaryList)) {
                    eduAddressStatisticsVOS.addAll(primaryList);
                }
                if (!CollectionUtils.isEmpty(juniorList)) {
                    eduAddressStatisticsVOS.addAll(juniorList);
                }
                // 合并后按未审核数量字段降序排序
                eduAddressStatisticsVOS.sort(Comparator.comparing(EduAddressStatisticsVO::getCount).reversed());
            } else {
                // 有传入学段，直接按传入的学段查询一次
                eduAddressStatisticsVOS = baseMapper.toBeReviewedAddressStatistics(vo);
            }
        } else {
            // 如果没有传入本年本学段标志
            eduAddressStatisticsVOS = baseMapper.toBeReviewedAddressStatistics(vo);
        }

        return CollectionUtils.isEmpty(eduAddressStatisticsVOS) ? new ArrayList<>() : eduAddressStatisticsVOS;
    }

    @Override
    public void resetAddressMatchingStatus() {
        UpdateWrapper<EduAddress> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(EduAddress::getMatchingStatus, MatchingStatusEnum.NODO.getType())
               .set(EduAddress::getMatchingMessage, "")
                .eq(EduAddress::getYear, eduHelper.thisYear())
                .eq(EduAddress::getMatchingStatus, MatchingStatusEnum.FAIL.getType());
        this.update(updateWrapper);
    }

}
